package pdfsetter.core;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import pdfsetter.core.pages.PageInfo;
import pdfsetter.core.pages.PageRectangle;
import pdfsetter.core.pages.PageType;
import pdfsetter.core.schema.AutomaticDocumentSchemaPattern;
import pdfsetter.core.schema.DocumentSchemaPattern;
import pdfsetter.core.schema.SimpleDocumentSchemaPattern;
import pdfsetter.core.schema.SinglePageSchema;
import pdfsetter.core.schema.advanced.AttachedFilePageSelector;
import pdfsetter.core.schema.advanced.AutomaticConsecutiveProcessPattern;
import pdfsetter.core.schema.advanced.AutomaticRepetitiveProcessPattern;
import pdfsetter.core.schema.advanced.ConsecutiveFileListProcessPattern;
import pdfsetter.core.schema.advanced.FilePageSelector;
import pdfsetter.core.schema.advanced.FillingSchemaPattern;
import pdfsetter.core.schema.advanced.RepetitiveFileListProcessPattern;
import pdfsetter.core.schema.onefile.OneFileDocumentSchemaPattern;
import pdfsetter.core.schema.onefile.SimpleOneFileDocumentSchemaPattern;
import pdfsetter.core.schema.selectors.CompoundFilePageSelector;
import pdfsetter.core.schema.selectors.LeapingPageSelector;
import pdfsetter.core.schema.selectors.NormalPageSelector;
import pdfsetter.core.schema.selectors.RangePageSelector;

import com.thoughtworks.xstream.XStreamException;

public class XMLSerializationExample {
    public static XMLObjectSerializer serializer = new XMLObjectSerializer();

    public static void saveSomePageSchemas() throws XStreamException, FileNotFoundException {
        PageInfo a4 = new PageInfo(PageType.A4);
        ArrayList<PageRectangle> loc0 = new ArrayList<PageRectangle>();
        loc0.add(new PageRectangle(0, 0, a4.getWidth(), a4.getHeight(), 0));
        SinglePageSchema pageSchema0 = new SinglePageSchema("Normal A4", a4, loc0);

        serializer.writeObject(pageSchema0, "out-test/normal_A4.xml");

        PageInfo a4page = new PageInfo(PageType.A4).rotate();
        ArrayList<PageRectangle> locations = new ArrayList<PageRectangle>();
        locations.add(new PageRectangle(0, 0, a4page.getWidth() / 2, a4page.getHeight(), 0));
        locations.add(new PageRectangle(a4page.getWidth() / 2, 0, a4page.getWidth() / 2, a4page.getHeight(), 0));
        SinglePageSchema pageSchema = new SinglePageSchema("2xA5 on A4", a4page, locations);

        serializer.writeObject(pageSchema, "out-test/two_A5_on_A4.xml");

        ArrayList<PageRectangle> loc = new ArrayList<PageRectangle>();
        loc.add(new PageRectangle(0, 0, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        loc.add(new PageRectangle(a4.getWidth() / 2, 0, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        loc.add(new PageRectangle(0, a4.getHeight() / 2, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        loc.add(new PageRectangle(a4.getWidth() / 2, a4.getHeight() / 2, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        SinglePageSchema pageSchema2 = new SinglePageSchema("4xA5 on A4", a4, loc);

        serializer.writeObject(pageSchema2, "out-test/four_A5_on_A4.xml");
    }

    public static void saveSomeFillingSchemas() throws XStreamException, FileNotFoundException {
        FilePageSelector normal = new NormalPageSelector();
        FillingSchemaPattern joinAll = new AutomaticConsecutiveProcessPattern(normal);
        FillingSchemaPattern mixAll = new AutomaticRepetitiveProcessPattern(normal);

        serializer.writeObject(joinAll, "out-test/joinAll.xml");
        serializer.writeObject(mixAll, "out-test/mixAll.xml");

        List<AttachedFilePageSelector> atchList = new LinkedList<AttachedFilePageSelector>();
        atchList.add(new AttachedFilePageSelector(normal, 0));
        atchList.add(new AttachedFilePageSelector(normal, 1));
        FillingSchemaPattern joinTwo = new ConsecutiveFileListProcessPattern(atchList);
        FillingSchemaPattern mixTwo = new RepetitiveFileListProcessPattern(atchList);

        serializer.writeObject(joinTwo, "out-test/joinTwo.xml");
        serializer.writeObject(mixTwo, "out-test/mixTwo.xml");

        FilePageSelector leapTwo = new LeapingPageSelector(2);
        List<AttachedFilePageSelector> atchList2 = new LinkedList<AttachedFilePageSelector>();
        atchList2.add(new AttachedFilePageSelector(leapTwo, 0));
        FillingSchemaPattern onlyOdd = new ConsecutiveFileListProcessPattern(atchList2);

        List<AttachedFilePageSelector> atchList3 = new LinkedList<AttachedFilePageSelector>();
        atchList3.add(new AttachedFilePageSelector(new CompoundFilePageSelector(new RangePageSelector(1), leapTwo), 0));
        FillingSchemaPattern onlyEven = new ConsecutiveFileListProcessPattern(atchList3);

        serializer.writeObject(onlyOdd, "out-test/oneFile_onlyOddPages.xml");
        serializer.writeObject(onlyEven, "out-test/oneFile_onlyEvenPages.xml");
    }

    public static void saveSomeDocumentSchemaPatterns() throws XStreamException, FileNotFoundException {
        DocumentSchemaPattern simpleJoin = new SimpleDocumentSchemaPattern((SinglePageSchema) serializer.readObject("out-test/two_A5_on_A4.xml"),
                (FillingSchemaPattern) serializer.readObject("out-test/joinAll.xml"));
        serializer.writeObject(simpleJoin, "out-test/joinAll_2in1_doc.xml");

        List<OneFileDocumentSchemaPattern> ofDocPat = new LinkedList<OneFileDocumentSchemaPattern>();
        ofDocPat.add(new SimpleOneFileDocumentSchemaPattern((SinglePageSchema) serializer.readObject("out-test/normal_A4.xml"), new RangePageSelector(0, 0)));
        ofDocPat.add(new SimpleOneFileDocumentSchemaPattern((SinglePageSchema) serializer.readObject("out-test/four_A5_on_A4.xml"), new RangePageSelector(1)));
        DocumentSchemaPattern autChapters = new AutomaticDocumentSchemaPattern(ofDocPat);

        serializer.writeObject(autChapters, "out-test/auto_first-A4_rest-4in1_doc.xml");
    }

    public static void main(String[] args) throws XStreamException, FileNotFoundException {
        saveSomePageSchemas();
        saveSomeFillingSchemas();
        saveSomeDocumentSchemaPatterns();
    }
}
